﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Web.UI.WebControls;

namespace DBCore
{
    public static class Extend
    {
        #region Extend Object
        public static object Get(string propertyname, object context)
        {
            object result = null;
            var t = context.GetType();
            if (propertyname != string.Empty)
            {
                var p = t.GetProperty(propertyname);
                if (p != null)
                {
                    result = p.GetValue(context, null);
                }
                if (result == null)
                {
                    var f = t.GetField(propertyname);
                    if (f != null)
                    {
                        result = f.GetValue(context);
                    }
                }
                if (result == null)
                {
                    MethodInfo m;
                    try
                    {
                        m = t.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public);
                    }
                    catch
                    {
                        int tint;
                        m = t.GetMethod("get_Item", int.TryParse(propertyname, out tint) ? new Type[] { typeof(Int32) } : new Type[] { typeof(String) });
                    }
                    if (m != null)
                    {
                        result = m.Invoke(context, new object[] { propertyname });
                    }
                }
            }
            return result;
        }

        public static object Get(this object o, string propertyname)
        {
            return Get(propertyname, o);
        }

        public static System.Web.UI.LiteralControl ToLiteral(this object o)
        {
            return new System.Web.UI.LiteralControl((o ?? "").ToString());
        }

        public static string ToDateString(this object time)
        {
            return Convert.ToDateTime(time).ToShortDateString();
        }

        /// <summary>
        /// 返回一个指定类型的参数值,如果类型转换异常则返回默认值
        /// </summary>
        public static T ChanageType<T>(this object obj, T defaultvalue)
        {
            if (obj == null || obj.ToString() == "")
                return defaultvalue;
            try
            {
                return (T)Convert.ChangeType(obj, typeof(T));
            }
            catch
            {
                return defaultvalue;
            }
        }
        /// <summary>
        /// 返回一个指定类型的参数值
        /// </summary>
        public static T ChanageType<T>(this object obj)
        {
            return ChanageType(obj, default(T));
        }
        #endregion

        #region Extend List
        public static string Join<T>(this List<T> o, string joinstr)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < o.Count; i++)
            {
                sb.Append(o[i].ToString());
                if (i != o.Count - 1)
                {
                    sb.Append(joinstr);
                }
            }
            return sb.ToString();
        }
        public static void Push<T>(this List<T> o, T item)
        {
            if (!o.Contains(item))
            {
                o.Add(item);
            }
        }

        public static List<T> Clone<T>(this List<T> o)
        {
            return o.ToList();
        }


        public static string ToJson<T>(this IList<T> IL, string jsonName)
        {
            var Json = new StringBuilder();
            Json.Append("{\"" + jsonName + "\":[");
            if (IL.Count > 0)
            {
                for (int i = 0; i < IL.Count; i++)
                {
                    T obj = Activator.CreateInstance<T>();
                    var type = obj.GetType();
                    var pis = type.GetProperties();
                    Json.Append("{");
                    for (int j = 0; j < pis.Length; j++)
                    {
                        Json.Append("\"" + pis[j].Name.ToString() + "\":\"" + pis[j].GetValue(IL[i], null) + "\"");
                        if (j < pis.Length - 1)
                        {
                            Json.Append(",");
                        }
                    }
                    Json.Append("}");
                    if (i < IL.Count - 1)
                    {
                        Json.Append(",");
                    }
                }
            }
            Json.Append("]}");
            return Json.ToString();
        }
        #endregion

        #region Extend Enum
        public static string GetItem(this Enum o, object itemname)
        {
            return Enum.Parse(o.GetType(), itemname.ToString()).ToString();
        }


        public static System.Web.UI.WebControls.ListItemCollection GetItems(this Enum o, int itemvalue)
        {
            var coll = new System.Web.UI.WebControls.ListItemCollection();
            foreach (var s in o.GetType().GetFields())
            {
                if (s.FieldType.IsEnum)
                {
                    var text = s.Name;
                    var value = ((int)o.GetType().InvokeMember(text, BindingFlags.GetField, null, null, null)).ToString();
                    var attrs = (DescriptionAttribute[])s.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (attrs.Length > 0)
                    {
                        text = attrs[0].Description;
                    }
                    var li = new System.Web.UI.WebControls.ListItem(text, value);
                    if (itemvalue.ToString() == value) li.Selected = true;
                    coll.Add(li);
                }
            }
            return coll;
        }

        public static System.Web.UI.WebControls.ListItemCollection GetItems(this Enum o, string itemvalue)
        {
            var coll = new System.Web.UI.WebControls.ListItemCollection();
            foreach (var s in o.GetType().GetFields())
            {
                if (s.FieldType.IsEnum)
                {
                    string text = s.Name;
                    string value = ((int)o.GetType().InvokeMember(text, BindingFlags.GetField, null, null, null)).ToString();
                    var li = new System.Web.UI.WebControls.ListItem(text, value);
                    if (itemvalue.ToString() == text) li.Selected = true;
                    coll.Add(li);
                }
            }
            return coll;
        }


        public static System.Web.UI.WebControls.ListItemCollection GetItems(this Enum o, int itemvalue, Func<string, string> funcText)
        {
            var coll = new System.Web.UI.WebControls.ListItemCollection();
            foreach (var s in o.GetType().GetFields())
            {
                if (s.FieldType.IsEnum)
                {
                    var text = funcText(s.Name);
                    var value = ((int)o.GetType().InvokeMember(s.Name, BindingFlags.GetField, null, null, null)).ToString();
                    var li = new System.Web.UI.WebControls.ListItem(text, value);
                    if (itemvalue.ToString() == s.Name) li.Selected = true;
                    coll.Add(li);
                }
            }
            return coll;
        }
        #endregion

        #region Extend ListItemColl
        public static ListItemCollection AddIn(this ListItemCollection coll, ListItem li)
        {
            coll.Add(li);
            return coll;
        }
        public static ListItemCollection AddNonValueIn(this ListItemCollection coll, string name)
        {
            coll.Insert(0, new ListItem(name, ""));
            return coll;
        }
        public static ListItemCollection Load(this ListItemCollection coll, ListItemCollection source)
        {
            foreach (System.Web.UI.WebControls.ListItem li in source)
            {
                coll.Add(li);
            }
            return coll;
        }
        #endregion

        #region Extend DataSet and DataTable

        /// <summary>
        /// 将DataSet 转换为 实体类List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(this System.Data.DataSet ds) where T : Entity
        {
            var list = new List<T>();
            if (ds != null && ds.Tables.Count != 0 && ds.Tables[0].Rows.Count != 0)
            {
                list.AddRange(from DataRow row in ds.Tables[0].Rows select new BaseBLL<T>().GetModelByDataRow(row));
            }
            return list;
        }

        /// <summary>
        /// 将DataSet转换为指定的List类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ds"></param>
        /// <param name="func">转换函数</param>
        /// <returns></returns>
        public static List<T> ToList<T>(this System.Data.DataSet ds, Func<System.Data.DataRow, T> func)
        {
            var list = new List<T>();
            if (ds != null && ds.Tables.Count != 0 && ds.Tables[0].Rows.Count != 0)
            {
                list.AddRange(from DataRow row in ds.Tables[0].Rows select func(row));
            }
            return list;
        }

        /// <summary>
        /// 通过将一个可循环访问的枚举转换为List对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerator"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(this IEnumerator<T> enumerator)
        {
            var list = new List<T>();
            while (enumerator.MoveNext())
            {
                list.Add((T)enumerator.Current);
            }
            return list;
        }

        public static string ToJson(this System.Data.DataSet ds, string jsonName)
        {
            return ds.ToJson(jsonName, row => true);
        }

        public static string ToJson(this System.Data.DataSet ds, string jsonName, Func<System.Data.DataRow, bool> func)
        {
            var Json = new StringBuilder();
            Json.Append("{\"" + jsonName + "\":[");
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                return ds.Tables[0].ToJson(jsonName, func);
            }
            Json.Append("]}");
            return Json.ToString();
        }

        public static string ToJson(this System.Data.DataTable dt, string jsonName)
        {
            return dt.ToJson(jsonName, row => true);
        }

        public static string ToJson(this System.Data.DataTable dt, string jsonName, Func<System.Data.DataRow, bool> func)
        {
            var Json = new StringBuilder();
            Json.Append("{\"" + jsonName + "\":[");
            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if (func(dt.Rows[i]))
                    {
                        Json.Append("{");
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":\"" + dt.Rows[i][j].ToString() + "\"");
                            if (j < dt.Columns.Count - 1)
                            {
                                Json.Append(",");
                            }
                        }
                        Json.Append("}");
                        if (i < dt.Rows.Count - 1)
                        {
                            Json.Append(",");
                        }
                    }
                }
            }
            Json.Append("]}");
            return Json.ToString();
        }

        #endregion

    }
}
